package ch.exm.storm.conditions;

import ch.exm.storm.query.relational.RelationalQuery;

public class Between extends AbstractSimpleCondition {
	
	public Between(Object first, Object second, Object third) {
		arguments = new Object[] { first, second,  third };
	}
	
	@Override
	public boolean evaluateRelationalCondition(RelationalQuery query, boolean inverse) {
		whereCondition = new StringBuilder(); 
		if (!isRelationalArgument(query, arguments[0])) return false;
		whereCondition.append(inverse ? getInverseConditionKeyword() : getConditionKeyword());
		if (!isRelationalArgument(query, arguments[1])) return false;
		whereCondition.append(" and ");
		if (!isRelationalArgument(query, arguments[2])) return false;
		return true;
	}
	
	public boolean matches(Object object) {
		Object firstValue = evaluteArgumentOn(arguments[0], object);
		Object secondValue = evaluteArgumentOn(arguments[1], object);
		Object thirdValue = evaluteArgumentOn(arguments[2], object);
		
		if (firstValue == null || secondValue == null || thirdValue == null) return false;
		if (!(firstValue instanceof Comparable) || !(secondValue instanceof Comparable) || !(thirdValue instanceof Comparable)) return false;
		Comparable<Object> firstComparable = (Comparable<Object>)firstValue;
		return firstComparable.compareTo(secondValue) >= 0 && firstComparable.compareTo(thirdValue) <= 0;
	}

	@Override
	protected String getConditionKeyword() {
		return (" between ");
	}
	
	@Override
	protected String getInverseConditionKeyword() {
		return (" not between ");
	}

	public static Between isBetween(Object first, Object second, Object third) {
		return new Between(first, second, third);
	}
}
